package com.ykg.util;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class JacksonUtil {

    private static final ObjectMapper OBJECT_MAPPER;

    static {
        OBJECT_MAPPER = new ObjectMapper();
        OBJECT_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        OBJECT_MAPPER.configure(JsonParser.Feature.ALLOW_NUMERIC_LEADING_ZEROS, true);
    }

    public static <T> T toBean(String jsonStr, Class<T> targetClass) {
        try {
            checkJsonStr(jsonStr);
            return OBJECT_MAPPER.readValue(jsonStr, targetClass);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 转换成泛型类
     * @param jsonStr json字符串
     * @param base 泛型类
     * @param parameterClasses 参数
     * @param <T> 泛型
     * @return 返回泛型类
     */
    public static <T> T toGenericClass(String jsonStr, Class<T> base, Class<?>... parameterClasses) {
        try {
            checkJsonStr(jsonStr);
            JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructParametricType(base, parameterClasses);
            return OBJECT_MAPPER.readValue(jsonStr, javaType);
        } catch (Exception e) {
            return null;
        }
    }

    public static <T> List<T> toList(String jsonStr, Class<T> itemClass) {
        try {
            checkJsonStr(jsonStr);
            JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructCollectionType(List.class, itemClass);
            return OBJECT_MAPPER.readValue(jsonStr, javaType);
        } catch (Exception e) {
            return Collections.emptyList();
        }
    }

    public static <K, V> Map<K, V> toMap(String jsonStr, Class<K> keyClass, Class<V> valueClass) {
        try {
            checkJsonStr(jsonStr);
            JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructMapType(Map.class, keyClass, valueClass);
            return OBJECT_MAPPER.readValue(jsonStr, javaType);
        } catch (Exception e) {
            return Collections.emptyMap();
        }
    }

    public static <T> Set<T> toSet(String jsonStr, Class<T> itemClass) throws IOException {
        try {
            checkJsonStr(jsonStr);
            JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructCollectionType(Set.class, itemClass);
            return OBJECT_MAPPER.readValue(jsonStr, javaType);
        } catch (Exception e) {
            return Collections.emptySet();
        }
    }

    public static JsonNode toJsonNode(String jsonStr) {
        try {
            checkJsonStr(jsonStr);
            return OBJECT_MAPPER.readTree(jsonStr);
        } catch (Exception e) {
            return null;
        }
    }

    public static String toJsonStr(Object o) {
        try {
            return OBJECT_MAPPER.writeValueAsString(o);
        } catch (Exception e) {
            return "";
        }
    }

    private static void checkJsonStr(String jsonStr) throws Exception {
        if (StringUtils.isEmpty(jsonStr)) {
            throw new Exception();
        }
    }


}
